package com.demo.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.demo.mapper.*;
import com.demo.pojo.entity.*;
import com.demo.service.NoticeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
public class NoticeServiceImpl implements NoticeService {

    @Autowired
    private NoticeMapper noticeMapper;

    @Autowired
    private StudentMapper studentMapper;

    @Autowired
    private StudentNoticeReadMapper studentNoticeReadMapper;

    @Autowired
    private ClazzMapper clazzMapper;

    @Autowired
    private ClazzTeacherMapper clazzTeacherMapper;

    // ==================== 通知管理 ====================

    @Override
    public IPage<Notice> getNoticeList(String publisherType, Long publisherId,
                                       String noticeType, String semester,
                                       Integer status, Integer page, Integer pageSize) {
        Page<Notice> pageParam = new Page<>(page, pageSize);
        QueryWrapper<Notice> qw = new QueryWrapper<>();

        if (publisherType != null && !publisherType.isEmpty()) {
            qw.eq("publisher_type", publisherType);
        }
        if (publisherId != null) {
            qw.eq("publisher_id", publisherId);
        }
        if (noticeType != null && !noticeType.isEmpty()) {
            qw.eq("notice_type", noticeType);
        }
        if (semester != null && !semester.isEmpty()) {
            qw.eq("semester", semester);
        }
        if (status != null) {
            qw.eq("status", status);
        }

        qw.orderByDesc("publish_time", "create_time");

        return noticeMapper.selectPage(pageParam, qw);
    }

    @Override
    @Transactional
    public Long createNotice(Notice notice) {
        // 设置默认值
        if (notice.getStatus() == null) {
            notice.setStatus(1); // 已发布
        }
        if (notice.getPublishTime() == null && notice.getStatus() == 1) {
            notice.setPublishTime(new Date());
        }
        if (notice.getCreateTime() == null) {
            notice.setCreateTime(new Date());
        }
        if (notice.getUpdateTime() == null) {
            notice.setUpdateTime(new Date());
        }

        // 插入通知
        noticeMapper.insert(notice);
        Long noticeId = notice.getNoticeId();

        // 为目标学生创建接收记录
        if (notice.getStatus() == 1) { // 只有已发布的通知才创建接收记录
            createStudentNoticeRecords(notice);
        }

        return noticeId;
    }

    @Override
    @Transactional
    public boolean updateNotice(Notice notice) {
        if (notice.getNoticeId() == null) {
            return false;
        }

        notice.setUpdateTime(new Date());
        
        // 如果状态改为已发布，设置发布时间
        if (notice.getStatus() != null && notice.getStatus() == 1 && notice.getPublishTime() == null) {
            notice.setPublishTime(new Date());
        }

        int rows = noticeMapper.updateById(notice);
        
        // 如果状态变为已发布，需要创建学生接收记录
        if (notice.getStatus() != null && notice.getStatus() == 1) {
            Notice fullNotice = noticeMapper.selectById(notice.getNoticeId());
            if (fullNotice != null) {
                createStudentNoticeRecords(fullNotice);
            }
        }

        return rows > 0;
    }

    @Override
    @Transactional
    public boolean deleteNotice(Long noticeId) {
        // 删除通知（会级联删除student_notice_read记录）
        int rows = noticeMapper.deleteById(noticeId);
        return rows > 0;
    }

    /**
     * 为通知创建学生接收记录
     */
    private void createStudentNoticeRecords(Notice notice) {
        List<Long> targetStudentIds = new ArrayList<>();

        String targetScope = notice.getTargetScope();
        String targetIds = notice.getTargetIds();

        if ("all".equalsIgnoreCase(targetScope)) {
            // 全体学生
            List<Student> allStudents = studentMapper.selectList(null);
            for (Student s : allStudents) {
                if (s.getStudentId() != null) {
                    targetStudentIds.add(s.getStudentId().longValue());
                }
            }
        } else if ("class".equalsIgnoreCase(targetScope) && targetIds != null && !targetIds.isEmpty()) {
            // 指定班级
            String[] clazzIdStrs = targetIds.split(",");
            for (String clazzIdStr : clazzIdStrs) {
                try {
                    Long clazzId = Long.parseLong(clazzIdStr.trim());
                    QueryWrapper<Student> qw = new QueryWrapper<>();
                    qw.eq("clazz_id", clazzId);
                    List<Student> students = studentMapper.selectList(qw);
                    for (Student s : students) {
                        if (s.getStudentId() != null) {
                            targetStudentIds.add(s.getStudentId().longValue());
                        }
                    }
                } catch (NumberFormatException e) {
                    // 忽略无效的班级ID
                }
            }
        } else if ("student".equalsIgnoreCase(targetScope) && targetIds != null && !targetIds.isEmpty()) {
            // 指定学生
            String[] studentIdStrs = targetIds.split(",");
            for (String studentIdStr : studentIdStrs) {
                try {
                    Long studentId = Long.parseLong(studentIdStr.trim());
                    targetStudentIds.add(studentId);
                } catch (NumberFormatException e) {
                    // 忽略无效的学生ID
                }
            }
        }

        // 批量插入学生接收记录
        for (Long studentId : targetStudentIds) {
            // 检查是否已存在
            QueryWrapper<StudentNoticeRead> qw = new QueryWrapper<>();
            qw.eq("student_id", studentId).eq("notice_id", notice.getNoticeId());
            StudentNoticeRead existing = studentNoticeReadMapper.selectOne(qw);
            
            if (existing == null) {
                StudentNoticeRead record = new StudentNoticeRead();
                record.setStudentId(studentId);
                record.setNoticeId(notice.getNoticeId());
                record.setReadStatus(0); // 未读
                record.setCreateTime(new Date());
                studentNoticeReadMapper.insert(record);
            }
        }
    }

    // ==================== 辅助方法 ====================

    @Override
    public List<Map<String, Object>> getClazzList() {
        List<Clazz> clazzList = clazzMapper.selectList(null);
        List<Map<String, Object>> result = new ArrayList<>();
        for (Clazz clazz : clazzList) {
            Map<String, Object> map = new HashMap<>();
            map.put("clazzId", clazz.getClazzId());
            map.put("clazzName", clazz.getClazzName());
            result.add(map);
        }
        return result;
    }

    @Override
    public List<Map<String, Object>> getStudentList() {
        List<Student> studentList = studentMapper.selectList(null);
        List<Map<String, Object>> result = new ArrayList<>();
        for (Student student : studentList) {
            Map<String, Object> map = new HashMap<>();
            map.put("studentId", student.getStudentId());
            map.put("stuName", student.getStuName());
            map.put("stuNo", student.getStuNo());
            result.add(map);
        }
        return result;
    }

    @Override
    public List<Map<String, Object>> getTeacherClasses(Long teacherId) {
        // 查询教师教授的班级ID列表
        List<Long> clazzIds = clazzTeacherMapper.getClazzIdsByTeacherId(teacherId);
        
        if (clazzIds == null || clazzIds.isEmpty()) {
            return new ArrayList<>();
        }
        
        // 根据班级ID查询班级信息
        List<Clazz> clazzList = clazzMapper.selectBatchIds(clazzIds);
        List<Map<String, Object>> result = new ArrayList<>();
        for (Clazz clazz : clazzList) {
            Map<String, Object> map = new HashMap<>();
            map.put("clazzId", clazz.getClazzId());
            map.put("clazzName", clazz.getClazzName());
            result.add(map);
        }
        return result;
    }

    // ==================== 学生接口 ====================

    @Override
    public List<Map<String, Object>> getStudentNotices(Long studentId, String semester) {
        // 查询学生的班级
        Student student = studentMapper.selectById(studentId);
        if (student == null) {
            return new ArrayList<>();
        }

        // 查询学生可见的通知
        QueryWrapper<Notice> qw = new QueryWrapper<>();
        qw.eq("status", 1); // 只查询已发布的通知

        // 目标范围：all 或包含该学生的class或直接指定该学生
        qw.and(wrapper -> {
            wrapper.eq("target_scope", "all");
            
            // 如果学生有班级，查询指定该班级的通知
            if (student.getClazzId() != null) {
                wrapper.or(w -> w.eq("target_scope", "class")
                        .and(w2 -> w2.like("target_ids", student.getClazzId().toString())));
            }
            
            // 查询直接指定该学生的通知
            wrapper.or(w -> w.eq("target_scope", "student")
                    .and(w2 -> w2.like("target_ids", studentId.toString())));
        });

        // 学期过滤
        if (semester != null && !semester.isEmpty()) {
            qw.eq("semester", semester);
        }

        qw.orderByDesc("priority", "publish_time");
        List<Notice> notices = noticeMapper.selectList(qw);

        // 查询已读状态
        QueryWrapper<StudentNoticeRead> rw = new QueryWrapper<>();
        rw.eq("student_id", studentId);
        List<StudentNoticeRead> reads = studentNoticeReadMapper.selectList(rw);
        
        Map<Long, StudentNoticeRead> readMap = new HashMap<>();
        for (StudentNoticeRead read : reads) {
            readMap.put(read.getNoticeId(), read);
        }

        // 组装结果
        List<Map<String, Object>> result = new ArrayList<>();
        for (Notice notice : notices) {
            Map<String, Object> map = new HashMap<>();
            map.put("noticeId", notice.getNoticeId());
            map.put("title", notice.getTitle());
            map.put("content", notice.getContent());
            map.put("publisherType", notice.getPublisherType());
            map.put("publisherId", notice.getPublisherId());
            map.put("publisherName", notice.getPublisherName());
            map.put("targetScope", notice.getTargetScope());
            map.put("noticeType", notice.getNoticeType());
            map.put("priority", notice.getPriority());
            map.put("semester", notice.getSemester());
            map.put("publishTime", notice.getPublishTime());
            
            // 已读状态
            StudentNoticeRead readRecord = readMap.get(notice.getNoticeId());
            map.put("read", readRecord != null && readRecord.getReadStatus() == 1);
            map.put("readTime", readRecord != null ? readRecord.getReadTime() : null);
            
            result.add(map);
        }

        return result;
    }

    @Override
    @Transactional
    public boolean markNoticeRead(Long studentId, Long noticeId) {
        QueryWrapper<StudentNoticeRead> qw = new QueryWrapper<>();
        qw.eq("student_id", studentId).eq("notice_id", noticeId);
        StudentNoticeRead exist = studentNoticeReadMapper.selectOne(qw);
        
        if (exist != null) {
            // 更新为已读
            if (exist.getReadStatus() == 0) {
                exist.setReadStatus(1);
                exist.setReadTime(new Date());
                studentNoticeReadMapper.updateById(exist);
            }
            return true;
        } else {
            // 创建已读记录
            StudentNoticeRead record = new StudentNoticeRead();
            record.setStudentId(studentId);
            record.setNoticeId(noticeId);
            record.setReadStatus(1);
            record.setReadTime(new Date());
            record.setCreateTime(new Date());
            return studentNoticeReadMapper.insert(record) > 0;
        }
    }

    // ==================== 兼容旧接口 ====================

    @Override
    @Deprecated
    public List<Map<String, Object>> listStudentNotices(Long studentId, String semester) {
        return getStudentNotices(studentId, semester);
    }

    @Override
    @Deprecated
    public boolean markRead(Long studentId, Long noticeId) {
        return markNoticeRead(studentId, noticeId);
    }
}
